import { ImportComment } from '@typings/comment'
import { storage } from '@utils/storage'
import { uploadImageCompressFileAPI } from '@/api/file'
import { ConditionDTO } from '@/api/entity/alarm'
import { alarmConditionStrMap } from '@/dataset'
import settings from '@/settings'
import { TabBarUtil } from '@/layout/components/tab-bar'
import router from '@/router'

/**
 * 注册一个组件
 * @param componentName 组件名称
 * @param component 组件对象
 */
export function registerComponentName (componentName: string, component: ImportComment) {
  return defineComponent({
    name: componentName,
    setup: (defineAsyncComponent(() => component) as any).setup
  })
}

/**
 * 验证码倒计时
 */
export class CountDownTimer {
  private readonly key: string
  private remainingCountdown: number
  private readonly callbackFn: { (countdown: number) }
  private readonly toCookie: boolean
  constructor (options: { key: string, toCookie?: boolean, fn: { (countdown: number) } }) {
    this.key = options.key + 'RemainingCountdown'
    this.callbackFn = options.fn
    this.toCookie = options.toCookie || false
    if (this.toCookie) {
      const endTime = storage.cookie.get(this.key)
      if (endTime) {
        const time = (Number(endTime) - Date.now()) / 1000
        if (time > 1) {
          this.setRemainingCountdown(~~time)
        }
      }
    }
  }

  public run (time: number) {
    const _time = Date.now() + (time * 1000)
    if (this.toCookie) {
      storage.cookie.set(this.key, _time.toString(), new Date(_time))
    }
    this.setRemainingCountdown(time)
  }

  // 设置剩余倒计时
  private setRemainingCountdown (countdown: number) {
    this.remainingCountdown = countdown
    this.startCountdownTimer()
  }

  // 倒计时定时器
  private countdownTimer: any
  // 启动倒计时定时器
  private startCountdownTimer () {
    this.countdownTimer && clearInterval(this.countdownTimer)
    this.countdownTimer = setInterval(() => {
      this.remainingCountdown--
      this.callbackFn(this.remainingCountdown)
      if (this.remainingCountdown <= 0) {
        clearInterval(this.countdownTimer)
      }
    }, 1000)
  }
}

/**
 * 文件工具
 */
export const FileUtil = {
  /**
   * 上传文件
   * @param file
   */
  updateFile (file: File) {
    return new Promise<string>((resolve) => {
      uploadImageCompressFileAPI(file).then((res) => {
        res.result().then((rdata) => {
          resolve(rdata.data)
        }).catch(() => {
          resolve(undefined)
        })
      }).catch(() => {
        resolve(undefined)
      })
    })
  },

  /**
   * 下载文件
   * @param file
   * @param fileName
   */
  downloadFile (file: File, fileName?: string) {
    const a = document.createElement('a')
    a.download = fileName || file.name
    const href = URL.createObjectURL(file)
    a.href = href
    a.click()
    URL.revokeObjectURL(href)
  },

  /**
   * 拼接图片前缀
   * @param url
   * @param defaultUrl
   */
  prefixImage (url?: string, defaultUrl?: string) {
    return url ? (settings.URL.IMAGE_PREFIX + url) : (defaultUrl || undefined)
  },
  // 默认图片枚举
  DefaultImage: {
    Avatar: new URL('@images/default/user.png', import.meta.url).toString(),
    Device: new URL('@images/default/device.svg', import.meta.url).toString()
  }
}

/**
 * 报警
 */
export const AlarmUtil = {
  formatCondition (condition: ConditionDTO) {
    if (condition) {
      let str = alarmConditionStrMap.get(condition.name)
      str = str.replace('A', condition.valueA)
      return str.replace('B', condition.valueB)
    } else {
      return '/'
    }
  }
}

/**
 * 前往编辑页面通用判断
 * @param option
 */
export function toEditPageCheck (option: {
  // 快捷跳转，如果没有填写checkExistFn则按id判断
  id?: string
  name: string,
  message: string,
  // 自定义判断是否存在相同的页面
  checkExistFn?(route: any): boolean,
  query: NonNullable<unknown>,
  params?: NonNullable<unknown>,
}) {
  const params = option.params || {}
  const _route = TabBarUtil.value.getTagInfo(option.name)
  option.checkExistFn ??= (route) => {
    return route && route.query.id !== option.id
  }
  if (option.checkExistFn(_route)) {
    ElMessageBox.confirm(option.message, '跳转提醒', {
      closeOnClickModal: false,
      distinguishCancelAndClose: true,
      confirmButtonText: '前往查看',
      cancelButtonText: '打开新页面'
    }).then(() => {
      TabBarUtil.value.selected(option.name)
    }).catch((e) => {
      if (e === 'cancel') {
        TabBarUtil.value.close(option.name)
        router.push({ name: option.name, query: option.query, params })
      }
    })
  } else {
    router.push({ name: option.name, query: option.query, params })
  }
}

/**
 * 使用keep-alive时，首次进入（F5进入的第一个页面）只会触发onMounted不会触发onActivated，
 * 如果再点开一个页面则会同时触发onMounted和onActivated，不确定是vue的机制还是bug
 */
export class MountedCheck {
  private _isMounted: boolean = null
  public start () {
    this._isMounted = true
  }

  public end () {
    setTimeout(() => {
      this._isMounted = false
    }, 32)
  }

  public isMounted () {
    return this._isMounted !== false
  }
}
